package com.iotcomm.server;

import com.iotcomm.model.UserInfo;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 服务器端界面控制器
 */
public class ServerController implements Initializable {
    private static final Logger logger = LoggerFactory.getLogger(ServerController.class);

    @FXML private TextField portField;
    @FXML private Button startButton;
    @FXML private Button stopButton;
    @FXML private Label statusLabel;
    @FXML private Label onlineCountLabel;
    @FXML private TableView<UserInfo> userTable;
    @FXML private TableColumn<UserInfo, String> usernameColumn;
    @FXML private TableColumn<UserInfo, String> ipColumn;
    @FXML private TableColumn<UserInfo, String> portColumn;
    @FXML private TableColumn<UserInfo, String> loginTimeColumn;
    @FXML private TableColumn<UserInfo, Long> messageCountColumn;
    @FXML private TableColumn<UserInfo, String> trafficColumn;
    @FXML private TextArea logArea;
    @FXML private LineChart<Number, Number> connectionChart;
    @FXML private NumberAxis xAxis;
    @FXML private NumberAxis yAxis;
    
    private ChatServer chatServer;
    private ObservableList<UserInfo> userList = FXCollections.observableArrayList();
    private XYChart.Series<Number, Number> connectionSeries;
    private ScheduledExecutorService chartUpdateExecutor;
    private int timeCounter = 0;
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // 初始化界面组件
        initializeComponents();
        
        // 初始化图表
        initializeChart();
        
        // 启动图表更新任务
        startChartUpdate();
    }
    
    /**
     * 初始化界面组件
     */
    private void initializeComponents() {
        // 设置默认端口
        portField.setText("8888");
        
        // 初始化按钮状态
        startButton.setDisable(false);
        stopButton.setDisable(true);
        
        // 初始化状态标签
        statusLabel.setText("服务器未启动");
        onlineCountLabel.setText("在线用户: 0");
        
        // 初始化用户表格
        initializeUserTable();
        
        // 初始化日志区域
        logArea.setEditable(false);
        logArea.setWrapText(true);
        
        // 添加日志
        appendLog("服务器界面初始化完成");
    }
    
    /**
     * 初始化用户表格
     */
    private void initializeUserTable() {
        usernameColumn.setCellValueFactory(new PropertyValueFactory<>("username"));
        ipColumn.setCellValueFactory(new PropertyValueFactory<>("ipAddress"));
        portColumn.setCellValueFactory(new PropertyValueFactory<>("clientPort"));
        messageCountColumn.setCellValueFactory(new PropertyValueFactory<>("messageCount"));
        trafficColumn.setCellValueFactory(cellData -> 
                new javafx.beans.property.SimpleStringProperty(cellData.getValue().getFormattedTraffic()));
        
        // 登录时间列需要格式化
        loginTimeColumn.setCellValueFactory(cellData -> {
            LocalDateTime loginTime = cellData.getValue().getLoginTime();
            String formattedTime = loginTime.format(DateTimeFormatter.ofPattern("MM-dd HH:mm:ss"));
            return new javafx.beans.property.SimpleStringProperty(formattedTime);
        });
        
        userTable.setItems(userList);
        
        // 设置表格列宽
        usernameColumn.setPrefWidth(120);
        ipColumn.setPrefWidth(120);
        portColumn.setPrefWidth(120);
        loginTimeColumn.setPrefWidth(120);
        messageCountColumn.setPrefWidth(80);
        trafficColumn.setPrefWidth(80);
    }
    
    /**
     * 初始化连接数图表
     */
    private void initializeChart() {
        xAxis.setLabel("时间 (秒)");
        yAxis.setLabel("在线用户数");
        yAxis.setAutoRanging(false);
        yAxis.setLowerBound(0);
        yAxis.setUpperBound(10);
        yAxis.setTickUnit(1);
        
        connectionSeries = new XYChart.Series<>();
        connectionSeries.setName("在线用户数");
        connectionChart.getData().add(connectionSeries);
        connectionChart.setCreateSymbols(false);
        connectionChart.setAnimated(false);
    }
    
    /**
     * 启动图表更新任务
     */
    private void startChartUpdate() {
        chartUpdateExecutor = Executors.newSingleThreadScheduledExecutor();
        chartUpdateExecutor.scheduleAtFixedRate(() -> {
            Platform.runLater(() -> {
                int userCount = userList.size();
                connectionSeries.getData().add(new XYChart.Data<>(timeCounter++, userCount));
                
                // 保持图表数据点数量在合理范围内
                if (connectionSeries.getData().size() > 60) {
                    connectionSeries.getData().remove(0);
                }
                
                // 动态调整Y轴范围
                if (userCount > yAxis.getUpperBound() - 2) {
                    yAxis.setUpperBound(userCount + 5);
                }
            });
        }, 0, 2, TimeUnit.SECONDS);
    }
    
    /**
     * 启动服务器
     */
    @FXML
    private void startServer() {
        try {
            int port = Integer.parseInt(portField.getText().trim());
            
            if (port < 1 || port > 65535) {
                showAlert("错误", "端口号必须在1-65535之间");
                return;
            }
            
            chatServer = new ChatServer(port);
            
            // 设置回调函数
            chatServer.setUserListUpdateCallback(this::updateUserList);
            chatServer.setServerStatusCallback(this::updateServerStatus);
            
            // 在新线程中启动服务器
            new Thread(() -> {
                try {
                    chatServer.start();
                } catch (Exception e) {
                    Platform.runLater(() -> {
                        appendLog("服务器启动失败: " + e.getMessage());
                        showAlert("错误", "服务器启动失败: " + e.getMessage());
                        resetButtonState();
                    });
                }
            }).start();
            
            // 更新界面状态
            startButton.setDisable(true);
            stopButton.setDisable(false);
            portField.setDisable(true);
            
            appendLog("正在启动服务器，端口: " + port);
            
        } catch (NumberFormatException e) {
            showAlert("错误", "请输入有效的端口号");
        } catch (Exception e) {
            logger.error("启动服务器时发生错误", e);
            showAlert("错误", "启动服务器时发生错误: " + e.getMessage());
        }
    }
    
    /**
     * 停止服务器
     */
    @FXML
    private void stopServer() {
        if (chatServer != null) {
            new Thread(() -> {
                chatServer.stop();
                Platform.runLater(this::resetButtonState);
            }).start();
            
            appendLog("正在停止服务器...");
        }
    }
    
    /**
     * 重置按钮状态
     */
    private void resetButtonState() {
        startButton.setDisable(false);
        stopButton.setDisable(true);
        portField.setDisable(false);
        statusLabel.setText("服务器未启动");
        onlineCountLabel.setText("在线用户: 0");
        userList.clear();
    }
    
    /**
     * 更新用户列表
     */
    private void updateUserList(List<UserInfo> users) {
        userList.clear();
        userList.addAll(users);
        onlineCountLabel.setText("在线用户: " + users.size());
        
        appendLog(String.format("用户列表更新，当前在线: %d 人", users.size()));
    }
    
    /**
     * 更新服务器状态
     */
    private void updateServerStatus(String status) {
        statusLabel.setText(status);
        appendLog("服务器状态: " + status);
    }
    
    /**
     * 添加日志
     */
    private void appendLog(String message) {
        Platform.runLater(() -> {
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
            String logMessage = String.format("[%s] %s%n", timestamp, message);
            logArea.appendText(logMessage);
            
            // 自动滚动到底部
            logArea.setScrollTop(Double.MAX_VALUE);
        });
    }
    
    /**
     * 显示警告对话框
     */
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
    
    /**
     * 清空日志
     */
    @FXML
    private void clearLog() {
        logArea.clear();
        appendLog("日志已清空");
    }
    
    /**
     * 刷新用户列表
     */
    @FXML
    private void refreshUserList() {
        if (chatServer != null) {
            List<UserInfo> users = chatServer.getOnlineUsers();
            updateUserList(users);
        }
    }
    
    /**
     * 关闭应用程序时的清理工作
     */
    public void shutdown() {
        if (chartUpdateExecutor != null) {
            chartUpdateExecutor.shutdown();
        }
        
        if (chatServer != null) {
            chatServer.stop();
        }
    }
}